﻿/*
 * Created by SharpDevelop.
 * User: Guy Fomi
 * Date: 2/6/2011
 * Time: 2:14 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections;
using System.Collections.Generic;
using HtmlAgilityPack;
using System.Web.Script.Serialization;
using FileSystemDatabase;
using TomatoSynchronizer.Entities;

namespace TomatoSynchronizer.Store
{
	/// <summary>
	/// Description of MappingStore.
	/// </summary>
	public class MappingStore
	{
		private Site _siteSrc;
		
		public Site SiteSrc {
			get { return _siteSrc; }
			set { _siteSrc = value; }
		}
		private Site _siteDest;
		
		public Site SiteDest {
			get { return _siteDest; }
			set { _siteDest = value; }
		}
		private string _entity;
		
		private List<Mapping> _mappings;
		
		public List<Mapping> Mappings {
			get { return _mappings; }
			set { _mappings = value; }
		}
		
		private JsonDatabase db;	
		
		public MappingStore()
		{			
		}	
		
		public void Truncate()
		{
			db.Truncate();
			_mappings.Clear();
		}
		
		public MappingStore(Site siteSrc,Site siteDest,string entity)
		{
			_siteSrc = siteSrc;
			_siteDest = siteDest;
			_entity = entity;
			
			db = new JsonDatabase("mappings/" + siteSrc.Name + ";" + siteDest.Name + "/" + entity);
			_mappings = new List<Mapping>();
			Mapping[] mappings = db.Read<Mapping>();
			
			foreach(Mapping mapping in mappings)
			{
				_mappings.Add(mapping);
			}
		}	
		
		public void Clean<T>(IStore<T> srcStore,IStore<T> destStore)
		{
			List<Mapping> goodMappings =  new List<Mapping>();
			foreach(Mapping mapping in _mappings)
			{
				T src = srcStore.LoadItem(mapping.SrcValue);
				T dest = destStore.LoadItem(mapping.DestValue);
				
				if(src != null && dest != null)
				{
					goodMappings.Add(mapping);
				}
				else
				{
					DeleteMapping(mapping);
				}
			}
			
			_mappings = goodMappings;
		}
		
		private void DeleteMapping(Mapping mapping)
		{
			db.Delete<Mapping>(mapping.SrcValue + "_" + mapping.DestValue);
		}

		private void SaveMapping(Mapping mapping)
		{
			db.Write<Mapping>(mapping,mapping.SrcValue + "_" + mapping.DestValue);
		}
		
		public void Save()
		{
			//we only save mappings that exists
			
			List<Mapping> newMappings = new List<Mapping>();
			foreach(Mapping mapping in _mappings)
			{
				if(mapping.Exists)
				{
					SaveMapping(mapping);
					newMappings.Add(mapping);
				}
				else
				{
					DeleteMapping(mapping);
				}
			}
			
			_mappings = newMappings;
			
			db.Write<MappingStore>(this,_entity);
		}
		
		public Mapping GetMapping(string srcValue,string destValue,string property)
		{			
			foreach(Mapping mapping in _mappings)
			{
				if(mapping.SrcValue == srcValue && mapping.DestValue == destValue && mapping.Property == property)
				{
					return mapping;
				}
			}
			
			return null;
		}

		public T GetMapping<T>(string srcValue,string property,Site site,string path)
		{			
			JsonDatabase Tdb = new JsonDatabase("sites/" + site.Name + "/" + path);
			foreach(Mapping mapping in _mappings)
			{
				if(mapping.SrcValue == srcValue && mapping.Property == property)
				{
					return Tdb.Read<T>(mapping.DestValue);
				}
			}
			
			return default(T);
		}
		
		public Mapping GetMapping(string srcValue,string property)
		{			
			foreach(Mapping mapping in _mappings)
			{
				if(mapping.SrcValue == srcValue && mapping.Property == property)
				{
					return mapping;
				}
			}
			
			return null;
		}	
	}
}
